package org.geotools.utils;

import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

import org.geotools.coverage.grid.GridCoverage2D;
import org.geotools.coverage.grid.io.AbstractGridFormat;
import org.geotools.data.DataStore;
import org.geotools.data.FeatureWriter;
import org.geotools.data.FileDataStoreFactorySpi;
import org.geotools.data.Transaction;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.shapefile.ShapefileDataStoreFactory;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.gce.geotiff.GeoTiffFormat;
import org.geotools.gce.geotiff.GeoTiffWriteParams;
import org.geotools.gce.geotiff.GeoTiffWriter;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.parameter.GeneralParameterValue;
import org.opengis.parameter.ParameterValueGroup;
import org.opengis.referencing.crs.CoordinateReferenceSystem;

public class FileUtils {
	public static DataStore copyShapefile(String srcfilepath, String destfilepath) {
		try {
			// original shapefile
			ShapefileDataStore sourceDS = (ShapefileDataStore) new ShapefileDataStoreFactory()
					.createDataStore(new File(srcfilepath).toURI().toURL());
			// create target shapefile object
			Map<String, Serializable> params = new HashMap<String, Serializable>();
			FileDataStoreFactorySpi factory = new ShapefileDataStoreFactory();
			params.put(ShapefileDataStoreFactory.URLP.key, new File(
					destfilepath).toURI().toURL());
			ShapefileDataStore destDS = (ShapefileDataStore) factory
					.createNewDataStore(params);
			// set properties
			SimpleFeatureSource fs = sourceDS.getFeatureSource(sourceDS
					.getTypeNames()[0]);
			// simpleFeatureType can be set not only by retype,but also by
			// fs.getSchema
			destDS.createSchema(SimpleFeatureTypeBuilder.retype(fs.getSchema(),
					DefaultGeographicCRS.WGS84));
			// set writer
			FeatureWriter<SimpleFeatureType, SimpleFeature> writer = destDS
					.getFeatureWriter(destDS.getTypeNames()[0],
							Transaction.AUTO_COMMIT);
			// write record
			SimpleFeatureIterator it = fs.getFeatures().features();
			try {
				while (it.hasNext()) {
					SimpleFeature f = it.next();
					SimpleFeature fNew = writer.next();
					fNew.setAttributes(f.getAttributes());
					writer.write();
				}
			} finally {
				it.close();
			}
			writer.close();
			destDS.dispose();
			sourceDS.dispose();
			return destDS;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	public static GridCoverage2D exportRasterfile(GridCoverage2D cov,String destfilepath){
		File outtiff =new File(destfilepath);
        try { 
            GeoTiffWriteParams wp = new GeoTiffWriteParams(); 
            wp.setCompressionMode(GeoTiffWriteParams.MODE_EXPLICIT); 
            wp.setCompressionType("LZW"); 
            ParameterValueGroup params = new GeoTiffFormat().getWriteParameters(); 
            params.parameter(AbstractGridFormat.GEOTOOLS_WRITE_PARAMS.getName().toString()).setValue(wp); 
            GeoTiffWriter writer = new GeoTiffWriter(outtiff); 
            writer.write(cov, (GeneralParameterValue[]) params.values().toArray(new GeneralParameterValue[1])); 
            writer.dispose();
            System.out.println(outtiff);
        } catch (Exception e) { 
        	System.out.println("exception while writing geotiff."); 
            e.printStackTrace(); 
        } 
		return cov;		
	}

	public static DataStore exportShapefile(SimpleFeatureSource featureSource, String destfilepath)throws IOException {
		try {
			File file = new File(destfilepath);
			Map<String, Serializable> params = new HashMap<String, Serializable>();
			params.put(ShapefileDataStoreFactory.URLP.key, file.toURI().toURL());
			SimpleFeatureCollection features = featureSource.getFeatures();
			SimpleFeatureType schema = featureSource.getSchema();
			CoordinateReferenceSystem sourceCRS = schema.getCoordinateReferenceSystem();
			ShapefileDataStore ds = (ShapefileDataStore) new ShapefileDataStoreFactory()
					.createNewDataStore(params);
			SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();
			FileDataStoreFactorySpi factory = new ShapefileDataStoreFactory();
			ShapefileDataStore destDS = (ShapefileDataStore) factory
					.createNewDataStore(params);
			// simpleFeatureType can be set not only by retype,but also by
			// fs.getSchema
			destDS.createSchema(SimpleFeatureTypeBuilder.retype(
					featureSource.getSchema(), sourceCRS));
			// set writer
			FeatureWriter<SimpleFeatureType, SimpleFeature> writer = destDS
					.getFeatureWriter(destDS.getTypeNames()[0],
							Transaction.AUTO_COMMIT);
			// write record
			SimpleFeatureIterator it = featureSource.getFeatures().features();
			try {
				while (it.hasNext()) {
					SimpleFeature f = it.next();
					SimpleFeature fNew = writer.next();
					fNew.setAttributes(f.getAttributes());
					writer.write();
				}
			} finally {
				it.close();
			}
			writer.close();
			destDS.dispose();
			// featureSource.dispose();
			return destDS;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
}
